home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Sound / SPlayer / Socks5 / src / lib / rld.c < prev    next >
C/C++ Source or Header  |  1998-07-20  |  14KB  |  293 lines

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6.  
  7. /*
  8.  * $Id: rld.c,v 1.33.4.2 1998/06/29 22:42:35 salman Exp $
  9.  */
  10.  
  11. /* This file has all the stubs to get the "real" functions out of libc,      */
  12. /* libnsl or libsocket.  Sometimes we need the "real" function, because      */
  13. /* we've replaced it (i.e. connect), sometimes we need it because we will    */
  14. /* have mangled some static data that it keeps around (i.e. getenv).         */
  15. #include "socks5p.h"
  16. #include "addr.h"
  17. #include "log.h"
  18.  
  19. #ifdef HAVE_DLOPEN
  20.  
  21. #include <dlfcn.h>
  22.  
  23. #ifndef RTLD_LAZY
  24. #define RTLD_LAZY 1
  25. #endif
  26. #ifndef RTLD_GLOBAL
  27. #define RTLD_GLOBAL 0
  28. #endif
  29. #ifndef LIBC_NAME
  30. #define LIBC_NAME NULL
  31. #endif
  32. #ifndef LIBNSL_NAME
  33. #define LIBNSL_NAME NULL
  34. #endif
  35. #ifndef LIBRESOLV_NAME
  36. #define LIBRESOLV_NAME NULL
  37. #endif
  38. #ifndef LIBSOCKET_NAME
  39. #define LIBSOCKET_NAME NULL
  40. #endif
  41. #ifndef LIBDGC_NAME
  42. #define LIBDGC_NAME NULL
  43. #endif
  44.  
  45. /* Lets hope we don't have to do this for too many OS's...Maybe configure    */
  46. /* should figure it out...?                                                  */
  47. #define TRY_LIBC        (1 << 0)
  48. #define TRY_LIBNSL      (1 << 1)
  49. #define TRY_LIBSOCKET   (1 << 2)
  50. #define TRY_LIBRESOLV   (1 << 3)
  51.  
  52. #define NO_RTLD_NEXT    (1 << 4)
  53. #define USE_RTLD_GLOBAL (1 << 5)
  54.  
  55. #ifdef FOR_SHARED_LIBRARY
  56.  
  57. #define GETSYM(handle, libname, flags)                                       \
  58.      if (!(handle) && ((handle) = dlopen((libname), (flags))) == NULL) {     \
  59.     return;                                     \
  60.      } else if ((*fptr = dlsym((handle), name)) != NULL) {                   \
  61.         return;                                                              \
  62.      } else
  63.  
  64. #define DGETSYM(handle, libname, flags)                                      \
  65.      if (!(handle) && ((handle) = dlopen((libname), (flags))) == NULL) {     \
  66.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Unable to open shared library: %s", (libname)); \
  67.      } else if ((*fptr = dlsym((handle), name)) != NULL) {                   \
  68.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Found %s in %s%s", name, (libname), libmask&USE_RTLD_GLOBAL?"(g)":"");  \
  69.         return;                                                              \
  70.      } else
  71.  
  72. #define GETSYMHANDLE(mask, handle, libname, envname, flags)                  \
  73.     if (libmask & (mask)) {                                                  \
  74.     static void *(handle) = NULL;                                        \
  75.         char *lname = (envname)?getenv((envname)):NULL;                      \
  76.     if (lname == NULL) lname = (libname);                                \
  77.         if (lname) GETSYM((handle), lname, (flags));                         \
  78.     } else
  79.  
  80. #define DGETSYMHANDLE(mask, handle, libname, envname, flags)                 \
  81.     if (libmask & (mask)) {                                                  \
  82.     static void *(handle) = NULL;                                        \
  83.         char *lname = (envname)?getenv((envname)):NULL;                      \
  84.     if (lname == NULL) lname = (libname);                                \
  85.         if (lname) DGETSYM((handle), lname, (flags));                        \
  86.     } else
  87.  
  88. #define GETFUNC(name, flags, invalid, cast, args, rtype)                     \
  89.     static void *func = NULL;                                                \
  90.     static rtype rval;                                                       \
  91.     GetOriginalFunc(&func, (name), (flags));                                 \
  92.     if (!func || func == (void *)-1) return (invalid);                       \
  93.     lsInRLDFunctions = 1;                                                      \
  94.     rval = (cast func)args;                                                  \
  95.     lsInRLDFunctions = 0;                                                      \
  96.     return rval
  97.  
  98. #define DGETFUNC(name, flags, invalid, cast, args, rtype)                    \
  99.     static void *func = NULL;                                                \
  100.     static rtype rval;                                                       \
  101.     DGetOriginalFunc(&func, (name), (flags));                                 \
  102.     if (!func || func == (void *)-1) return (invalid);                       \
  103.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: Found %s at %p", (name)+1, func);     \
  104.     lsInRLDFunctions = 1;                                                      \
  105.     rval = (cast func)args;                                                  \
  106.     lsInRLDFunctions = 0;                                                      \
  107.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: %s returned: %x", (name)+1, (rval));  \
  108.     return rval
  109.  
  110. extern int lsInRLDFunctions;
  111.  
  112. /* Look up name in libc.so, libnsl.so, and libsocket.so, if its there return */
  113. /* the symbol we found, otherwise return NULL...                             */
  114. static void GetOriginalFunc(void **fptr, char *name, int libmask) {
  115.     /* Synchronize access to func and lib opening functions if we can...     */
  116.  
  117. #ifndef __FreeBSD__
  118.     name++;
  119. #endif
  120.  
  121.     if (*fptr) return;
  122.  
  123.     /* Still have to figure out what OSs USE_RTLD_NEXT is valid for.  For    */
  124.     /* most that I've tried, it hasn't worked right...                       */
  125. #if defined(RTLD_NEXT) && defined(USE_RTLD_NEXT)
  126.     if (name && ~libmask & NO_RTLD_NEXT && (*fptr = dlsym(RTLD_NEXT, name)) != NULL) {
  127.         return;
  128.     }
  129. #endif
  130.  
  131.     GETSYMHANDLE(TRY_LIBRESOLV, libresolv_handle, LIBRESOLV_NAME,  "LIBRESOLV_NAME", RTLD_LAZY);
  132.     GETSYMHANDLE(TRY_LIBNSL,    libnsl_handle,    LIBNSL_NAME,     "LIBNSL_NAME",    RTLD_LAZY);
  133.     GETSYMHANDLE(TRY_LIBSOCKET, libsocket_handle, LIBSOCKET_NAME,  "LIBSOCKET_NAME", RTLD_LAZY);
  134.     GETSYMHANDLE(TRY_LIBSOCKET, libdgc_handle,    LIBDGC_NAME,     "LIBDGC_NAME",    RTLD_LAZY);
  135.     GETSYMHANDLE(TRY_LIBC,      libc_handle,      LIBC_NAME,       "LIBC_NAME",      RTLD_LAZY);
  136. }
  137.  
  138. /* Look up name in libc.so, libnsl.so, and libsocket.so, if its there return */
  139. /* the symbol we found, otherwise return NULL...                             */
  140. static void DGetOriginalFunc(void **fptr, char *name, int libmask) {
  141.     /* Synchronize access to func and lib opening functions if we can...     */
  142.  
  143. #ifndef __FreeBSD__
  144.     name++;
  145. #endif
  146.  
  147.     if (*fptr) return;
  148.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: %s", name);
  149.  
  150.     /* Still have to figure out what OSs USE_RTLD_NEXT is valid for.  For    */
  151.     /* most that I've tried, it hasn't worked right...                       */
  152. #if defined(RTLD_NEXT) && defined(USE_RTLD_NEXT)
  153.     if (name && ~libmask & NO_RTLD_NEXT && (*fptr = dlsym(RTLD_NEXT, name)) != NULL) {
  154.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: Used RTLD_NEXT");
  155.         return;
  156.     }
  157. #endif
  158.  
  159.     DGETSYMHANDLE(TRY_LIBRESOLV, libresolv_handle, LIBRESOLV_NAME,  "LIBRESOLV_NAME", RTLD_LAZY);
  160.     DGETSYMHANDLE(TRY_LIBNSL,    libnsl_handle,    LIBNSL_NAME,     "LIBNSL_NAME",    RTLD_LAZY);
  161.     DGETSYMHANDLE(TRY_LIBSOCKET, libsocket_handle, LIBSOCKET_NAME,  "LIBSOCKET_NAME", RTLD_LAZY);
  162.     DGETSYMHANDLE(TRY_LIBSOCKET, libdgc_handle,    LIBDGC_NAME,     "LIBDGC_NAME",    RTLD_LAZY);
  163.     DGETSYMHANDLE(TRY_LIBC,      libc_handle,      LIBC_NAME,       "LIBC_NAME",      RTLD_LAZY);
  164.     
  165.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "RLD: Unable to find symbol %s in suggested places: %d", name, libmask);
  166. }
  167.  
  168. struct hostent *REAL(gethostbyname)(const char *name) {
  169.     struct hostent *hp;
  170.     static void *func = NULL;
  171.  
  172.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname: %s", name);
  173.     GetOriginalFunc(&func, "_gethostbyname", TRY_LIBC | TRY_LIBNSL | TRY_LIBRESOLV);
  174.     if (!func || func == (void *)-1) return NULL;
  175.  
  176.     lsInRLDFunctions = 1;
  177.     hp = ((struct hostent *(*)P((const char *)))func)(name);
  178.     lsInRLDFunctions = 0;
  179.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname results: %s %s", name, hp?hp->h_name:"???");
  180.     return hp;
  181. }
  182.  
  183. int REAL(getpeername) (S5IOHandle sd, ss *sa, int *slen) {
  184.     GETFUNC("_getpeername", TRY_LIBC | TRY_LIBSOCKET,  -1, (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  185. }
  186.  
  187. int REAL(getsockname) (S5IOHandle sd, ss *sa, int *slen) {
  188.     GETFUNC("_getsockname", TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  189. }
  190.     
  191. int REAL(accept)      (S5IOHandle sd, ss *sa, int *slen) {
  192.     GETFUNC("_accept",      TRY_LIBC | TRY_LIBSOCKET,  -1, (int (*)P((S5IOHandle, ss *, int *))),                            (sd, sa, slen), int);
  193. }
  194.  
  195. int REAL(connect)     (S5IOHandle sd, const ss *sa, int slen) {
  196.     GETFUNC("_connect",     TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, const ss *, int))),                        (sd, sa, slen), int);
  197. }
  198.  
  199. int REAL(bind)        (S5IOHandle sd, const ss *sa, int slen) {
  200.     GETFUNC("_bind",        TRY_LIBC | TRY_LIBSOCKET, -1,  (int (*)P((S5IOHandle, const ss *, int))),                        (sd, sa, slen), int);
  201. }
  202.  
  203. int REAL(recvfrom)    (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen, int f, ss *sa, int *slen) {
  204.     GETFUNC("_recvfrom",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, char *, int, int, ss *, int *))),           (sd, buf, blen, f, sa, slen), int);
  205. }
  206.  
  207. int REAL(sendto)      (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen, int f, const ss *sa, int slen) {
  208.     GETFUNC("_sendto",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const char *, int, int, const ss *, int))), (sd, buf, blen, f, sa, slen), int);
  209. }
  210.  
  211. int REAL(recvmsg)    (S5IOHandle sd, const ms *sa, int slen) {
  212.     GETFUNC("_recvmsg",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const ms *, int ))),           (sd, sa, slen), int);
  213. }
  214.  
  215. int REAL(sendmsg)      (S5IOHandle sd, const ms *sa, int slen) {
  216.     GETFUNC("_sendmsg",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const ms *, int))), (sd, sa, slen), int);
  217. }
  218.  
  219. int REAL(recv)        (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen, int f) {
  220.     GETFUNC("_recv",        TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, char *, int, int))),                        (sd, buf, blen, f), int);
  221. }
  222.  
  223. int REAL(send)        (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen, int f) {
  224.     GETFUNC("_send",        TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, const char *, int, int))),                  (sd, buf, blen, f), int);
  225. }
  226.  
  227. int REAL(shutdown)    (S5IOHandle sd, int how) {
  228.     GETFUNC("_shutdown",    TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, int))),                                     (sd, how), int);
  229. }
  230.  
  231. int REAL(listen)      (S5IOHandle sd, int n) {
  232.     GETFUNC("_listen",      TRY_LIBC | TRY_LIBSOCKET, -1, (int (*)P((S5IOHandle, int))),                                     (sd, n), int);
  233. }
  234.  
  235. S5IOHandle REAL(dup)  (S5IOHandle sd) {
  236.     GETFUNC("_dup",          TRY_LIBC,                S5InvalidIOHandle, (S5IOHandle (*)P((S5IOHandle))),                    (sd), S5IOHandle);
  237. }
  238.  
  239. S5IOHandle REAL(dup2) (S5IOHandle sd, S5IOHandle s2) {
  240.     GETFUNC("_dup2",         TRY_LIBC,                S5InvalidIOHandle, (S5IOHandle (*)P((S5IOHandle, S5IOHandle))),        (sd, s2), S5IOHandle);
  241. }
  242.  
  243. int REAL(close)       (S5IOHandle sd) {
  244.     GETFUNC("_close",       TRY_LIBC,                 -1, (int (*)P((S5IOHandle))),                                          (sd), int);
  245. }
  246.  
  247. int REAL(fclose)      (FILE *fp) {
  248.     GETFUNC("_fclose",     TRY_LIBC,                  -1, (int (*)P((FILE *))),                                              (fp), int);
  249. }
  250.  
  251. IORETTYPE REAL(read)  (S5IOHandle sd, IOPTRTYPE buf, IOLENTYPE blen) {
  252.     GETFUNC("_read",         TRY_LIBC,                -1, (IORETTYPE (*)P((S5IOHandle, IOPTRTYPE, IOLENTYPE))),              (sd, buf, blen), IORETTYPE);
  253. }
  254.  
  255. IORETTYPE REAL(write) (S5IOHandle sd, const IOPTRTYPE buf, IOLENTYPE blen) {
  256.     GETFUNC("_write",        TRY_LIBC,                -1, (IORETTYPE (*)P((S5IOHandle, const IOPTRTYPE, IOLENTYPE))),        (sd, buf, blen), IORETTYPE);
  257. }
  258.  
  259. struct tm *REAL(localtime)(const time_t *clock) {
  260.     static void *func = NULL;
  261.     static struct tm * rval;
  262.  
  263.     GetOriginalFunc(&func, "_localtime", TRY_LIBC);
  264.     if (!func || func == (void *)-1) return (NULL);
  265.     lsInRLDFunctions = 1;
  266.     rval = ((struct tm * (*)(const time_t *))func)(clock);
  267.     lsInRLDFunctions = 0;
  268.     return rval;
  269. }
  270.  
  271. void REAL(longjmp) (jmp_buf env, int val) {
  272.     static void *func = NULL;
  273.  
  274.     GetOriginalFunc(&func, "_longjmp", TRY_LIBC);
  275.     if (!func || func == (void *)-1) return; 
  276.  
  277.     lsInRLDFunctions = 0;
  278.     ((void (*)(jmp_buf, int))func)(env, val);
  279. }
  280.  
  281. int REAL(select)      (S5IOHandle wd, fd_set *rs, fd_set *ws, fd_set *es, struct timeval *to) {
  282.     GETFUNC("_select",       TRY_LIBC,                -1, (int (*)P((S5IOHandle, fd_set *, fd_set *, fd_set *, struct timeval *))), (wd, rs, ws, es, to), int);
  283. }
  284.  
  285. #ifdef HAVE_RRESVPORT
  286. S5IOHandle REAL(rresvport)   (int *port) {
  287.     GETFUNC("_rresvport",   TRY_LIBC | TRY_LIBSOCKET, S5InvalidIOHandle, (S5IOHandle (*)P((int *))),                         (port), S5IOHandle);
  288. }
  289. #endif
  290.  
  291. #endif /* FOR_SHARED_LIBRARY                                                 */
  292. #endif /* HAVE_DLOPEN        */
  293.